﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.Creation;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.Revit.RevitExtension;
using YJKArch.BalAndStepModule.CreateFootstep;
using HYView;

namespace YJKArch.BalAndStepModule
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	[Journaling(JournalingMode.NoCommandData)]
	public class CreateAbnormalBalcony : YJKCommandManual
	{
		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		protected override Result YJKExcute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			CmdViewType types = (CmdViewType)3;
			if (SwitchView.SetUsableView(types, commandData) != Autodesk.Revit.UI.Result.Succeeded)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			this.app = commandData.Application;
			this.rvt_UIdoc = this.app.ActiveUIDocument;
			this.m_doc = this.rvt_UIdoc.Document;
			if (CreateAbnormalBalcony._hWndRevit == null)
			{
				CreateAbnormalBalcony._hWndRevit = new WindowHandle(Process.GetCurrentProcess().MainWindowHandle);
			}
			this.DrawBalcony();
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public bool DrawBalcony()
		{
			Level genLevel = this.m_doc.ActiveView.GenLevel;
			IListDate.WallTypeList = Helper.GetSystemFamilyElementList<WallType>(this.m_doc);
			IListDate.FloorTypeList = Helper.GetSystemFamilyElementList<FloorType>(this.m_doc);
			Autodesk.Revit.Creation.Application create = this.app.Application.Create;
			WallType wallType = null;
			CreateAbnormalBalconyForm createAbnormalBalconyForm = new CreateAbnormalBalconyForm(this.m_doc);
			if (DialogResult.OK != createAbnormalBalconyForm.ShowDialog(CreateAbnormalBalcony._hWndRevit))
			{
				return false;
			}
			List<Curve> list = new List<Curve>();
			List<Curve> list2 = new List<Curve>();
			List<ModelCurve> list3 = new List<ModelCurve>();
			List<ModelCurve> list4 = new List<ModelCurve>();
			if (!this.DrawPolyline("请绘制异形阳台板栏杆部分边线: ", ref list, ref list3))
			{
				return false;
			}
			if (list.Count == 0)
			{
				return false;
			}
			XYZ endPoint = list[0].GetEndPoint(0);
			XYZ endPoint2 = list[list.Count - 1].GetEndPoint(1);
			if (!endPoint.IsAlmostEqualTo(endPoint2) && !this.DrawPolyline("请绘制异形阳台板靠墙部分边线: ", ref list2, ref list4) && list2.Count == 0)
			{
				Line line = YJKLineEx.YJKGetBound(endPoint2, endPoint);
				Transaction transaction = new Transaction(this.m_doc, "Polyline");
				transaction.Start();
				Plane plane = RevitVersionFuncs.CreatePlanByNormalAndOrigin(XYZ.BasisZ, XYZ.Zero);
				SketchPlane sketchPlane = SketchPlane.Create(this.m_doc, plane);
				list4.Add(this.m_doc.Create.NewModelCurve(line, sketchPlane));
				list2.Add(line);
				transaction.Commit();
			}
			ElementSet elementSet = new ElementSet();
			Transaction transaction2 = new Transaction(this.m_doc, "createBancony");
			transaction2.Start();
			if (AssistFunc.feetToMM(createAbnormalBalconyForm.wallHeight) < 100.0)
			{
				YJKMessageBox.Show("栏板高度最低为“100”");
				transaction2.RollBack();
				return true;
			}
			wallType = (Helper.GetSelectType<WallType>(this.m_doc, createAbnormalBalconyForm.wallTypestr) as WallType);
			CurveArray curveArray = new CurveArray();
			double elevation = genLevel.Elevation;
			double levelElevation = createAbnormalBalconyForm.levelElevation;
			double offset = wallType.Width / 2.0;
			try
			{
				List<LoopEdge> list5 = new List<LoopEdge>();
				foreach (Curve curveIn in list)
				{
					LoopEdge item = new LoopEdge(curveIn, LoopEdge.EdgeType.ET_Extensible, false, null);
					list5.Add(item);
				}
				foreach (Curve curve in list)
				{
					curveArray.Append(curve);
				}
				if (list2.Count > 0)
				{
					if (list2[0].GetEndPoint(0).IsAlmostEqualTo(endPoint))
					{
						for (int i = list2.Count - 1; i >= 0; i--)
						{
							LoopEdge loopEdge = new LoopEdge(list2[i], LoopEdge.EdgeType.ET_Fixed, true, null);
							list5.Add(loopEdge);
							curveArray.Append(loopEdge.GetCurve());
						}
					}
					else
					{
						foreach (Curve curve2 in list2)
						{
							LoopEdge item2 = new LoopEdge(curve2, LoopEdge.EdgeType.ET_Fixed, false, null);
							list5.Add(item2);
							curveArray.Append(curve2);
						}
					}
				}
				list5 = new EdgeLoopOffsetEditor(this.m_app).OffsetEdgeLoop(list5, offset);
				for (int j = 0; j < list.Count; j++)
				{
					LoopEdge loopEdge2 = list5[j];
					Wall wall = RevitVersionFuncs.NewWall(this.m_doc, loopEdge2.GetCurve(), wallType, genLevel, createAbnormalBalconyForm.wallHeight, createAbnormalBalconyForm.levelElevation, true, true);
					elementSet.Insert(wall);
				}
				FloorType floorType = Helper.GetSelectType<FloorType>(this.m_doc, createAbnormalBalconyForm.floorType) as FloorType;
				Floor floor = this.m_doc.Create.NewFloor(curveArray, floorType, genLevel, true);
				Parameter parameter = floor.get_Parameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM);
				if (parameter != null)
				{
					parameter.Set(createAbnormalBalconyForm.levelElevation);
				}
				elementSet.Insert(floor);
				transaction2.Commit();
			}
			catch (Exception)
			{
				transaction2.RollBack();
			}
			Transaction transaction3 = new Transaction(this.m_doc, "makegroup");
			transaction3.Start();
			try
			{
				RevitVersionFuncs.NewGroup(this.m_doc, elementSet);
				transaction3.Commit();
			}
			catch (Exception)
			{
				transaction3.RollBack();
			}
			if (createAbnormalBalconyForm.bCheckDeleteModelLine)
			{
				Transaction transaction4 = new Transaction(this.m_doc, "tranDel");
				transaction4.Start();
				foreach (ModelCurve modelCurve in list3)
				{
					this.m_doc.Delete(modelCurve.Id);
				}
				foreach (ModelCurve modelCurve2 in list4)
				{
					this.m_doc.Delete(modelCurve2.Id);
				}
				transaction4.Commit();
			}
			return true;
		}

		public bool DrawPolyline(string strPrompt, ref List<Curve> lstCurves, ref List<ModelCurve> lstModelCurves)
		{
			try
			{
				Polyline polyline = new Polyline(CreateAbnormalBalcony._hWndRevit, this.app);
				polyline.DrawPolylines(strPrompt);
				polyline.GetCurves(ref lstCurves);
				polyline.GetCurves(ref lstModelCurves);
				int count = lstCurves.Count;
			}
			catch (Exception)
			{
				return false;
			}
			return lstCurves.Count != 0;
		}

		public UIApplication app;

		public UIDocument rvt_UIdoc;

        public new Autodesk.Revit.DB.Document m_doc;

		public static WindowHandle _hWndRevit;
	}
}
